﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SelfMadeMillionaire.Core.Entities;
using SelfMadeMillionaire.Core.Enums;
using SelfMadeMillionaire.Core.Repositories;
using SelfMadeMillionaire.Core.Services;

namespace SelfMadeMillionaire.BLL.Services
{
    public class EmailSendService : IEmailSendService
    {
        private readonly IEmailService _emailService;
        private readonly IEmailSendRepository _emailSendRepository;
        private readonly ISubscriberRepository _subscriberRepository;

        public EmailSendService(IEmailSendRepository emailSendRepository, IEmailService emailService, ISubscriberRepository subscriberRepository)
        {
            _emailSendRepository = emailSendRepository;
            _emailService = emailService;
            _subscriberRepository = subscriberRepository;
        }

        public IEnumerable<Core.Entities.EmailSend> GetAll()
        {
            var email = _emailSendRepository.GetAll();
            return email;
        }

        public Core.Entities.EmailSend Add(Core.Entities.EmailSend emailSend)
        {
            var email = _emailSendRepository.Add(emailSend);
            return email;
        }

        public Core.Entities.EmailSend Update(Core.Entities.EmailSend emailSend)
        {
            var email = _emailSendRepository.Update(emailSend);
            return email;
        }

        public Core.Entities.EmailSend Get(int id)
        {
            var email = _emailSendRepository.Get(id);
            return email;
        }

        public void Remove(int id)
        {
            _emailSendRepository.Remove(id);
        }

        public void SendEmailTemplates()
        {
            IEnumerable<EmailSend> emailSendTemplates = _emailSendRepository.GetAll().Where(x => x.Status == (byte)StatusType.Active);
            if (!emailSendTemplates.Any())
            {
                return;
            }

            foreach (var template in emailSendTemplates)
            {
                var recipientList = new List<string>();
                recipientList = GetRecipients(template.AdditRecipients);


                // выбираем подписчиков, которые явно не отписывались от бесплатных рассылок.
                // следовательно они на них подписаны
                if (template.IsFreeSubscribers)
                {
                    recipientList.AddRange(_subscriberRepository.GetAll().
                        Where(s => s.Status == (byte)StatusType.Active
                            && (!s.MmmUnsubscribed || !s.SmmUnsubscribed)
                            && s.SubscriptionLevel == (byte)SubscriptionType.Free).
                        Select(s => s.Email));
                }

                // выбираем подписчиков, подписанных на Silver подписку SMM
                if (template.IsSilver)
                {
                    recipientList.AddRange(_subscriberRepository.GetAll().
                        Where(s => s.Status == (byte)StatusType.Active
                            && !s.SmmUnsubscribed
                            && (s.ProductType == (byte)ProductType.SelfMadeMillionaire || s.ProductType == (byte)ProductType.SelfAndMaggies)
                            && s.SubscriptionLevel == (byte)SubscriptionType.Silver
                            && s.EndDate >= DateTime.Now
                            && !recipientList.Contains(s.Email)).
                        Select(s => s.Email)
                    );
                }

                // выбираем подписчиков, подписанных на Gold подписку SMM
                if (template.IsGold)
                {
                    recipientList.AddRange(_subscriberRepository.GetAll().
                        Where(s => s.Status == (byte)StatusType.Active
                            && !s.SmmUnsubscribed
                            && (s.ProductType == (byte)ProductType.SelfMadeMillionaire || s.ProductType == (byte)ProductType.SelfAndMaggies)
                            && s.SubscriptionLevel == (byte)SubscriptionType.Gold
                            && s.EndDate >= DateTime.Now
                            && !recipientList.Contains(s.Email)).
                        Select(s => s.Email));
                }


                var sended = false;
                string err = "";

                foreach (var recipient in recipientList)
                {
                    try
                    {
                        _emailService.SendEmails(recipient, template.Subject, template.Body);
                        sended = true;
                        err = "";
                    }
                    catch (Exception ex)
                    {
                        sended = false;
                        err = ex.Message;
                    }
                }

                if (sended)
                {
                    template.SentDate = DateTime.Now;
                    template.Status = (byte)StatusType.None;
                    template.Message = "";
                    template.TriesCount = 0;
                }
                else
                {
                    template.Status = (byte)StatusType.Canceled;
                    template.Message = err;
                    template.TriesCount++;
                }
            }
            _emailSendRepository.Commit();
        }

        private List<string> GetRecipients(string recipients)
        {
            var recipientList = new List<string>();
            recipientList = recipients.Split(new char[] { ' ', ',', ';', '<', '>', '"' }).ToList();
            return recipientList;
        }
    }
}
